//
//  ZDPhotoBrowserCollectionView.swift
//  1026SwiftSinaWeiBo
//
//  Created by Apple on 15/11/7.
//  Copyright © 2015年 itcast. All rights reserved.
//

import UIKit
import SDWebImage

class ZDPhotoBrowserCollectionView: UICollectionView {

    //MARK: - 属性
    let layout = UICollectionViewFlowLayout()
    
    //MARK: - 构造函数
    init() {
    
        super.init(frame: CGRectZero, collectionViewLayout: layout)
        
        prepareUI()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    
    //MARK: - 准备UI
    private func prepareUI() {
    
        layout.itemSize = CGSize(width: UIScreen.width, height: UIScreen.height)
        layout.minimumInteritemSpacing = ZDCollectionViewPadding
        layout.minimumLineSpacing = ZDCollectionViewPadding
        
        //设置sectionInset 与右边间距10
        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: ZDCollectionViewPadding)
        
        //设置滚动方向
        layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
        
        //设置分页
        pagingEnabled = true
        
        //取消水平滚动条
        showsHorizontalScrollIndicator = false
        
        //取消水平方向弹簧效果
//        alwaysBounceHorizontal = false
        bounces = false
    }
}


///定义协议
protocol ZDPhotoBrowserCellDelegate: NSObjectProtocol {

    func viewForTransparent() -> UIView
    
    func scaleDismiss()
}


//MARK: - 自定义cell
class ZDPhotoBrowserCell: UICollectionViewCell {
    
    //定义代理属性
    weak var delegate: ZDPhotoBrowserCellDelegate?
    
    var model: ZDPhotoBrowserModel? {
    
        didSet {
            
            guard let url = model?.url else {
                
                print("url为空")
                return
            }
            
            //每次先清空imageView  避免cell复用带来影响
            imageView.image = nil
            //清除cell的相关属性
            clearCellAttributes()
        
            indicatorView.startAnimating()
   
            imageView.sd_setImageWithURL(url, completed: { (image, error, _, _) -> Void in
                
                self.indicatorView.stopAnimating()
                
                if error != nil {
                    
                    print("下载大图片失败")
                    
                    return
                }
                
//                print(image.size)
                
                self.layoutImageView(image)
                
//                print(self.imageView.frame)
            })
        }
    }
    
    
/*
    //模拟网络延时  发现cell存在复用
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (Int64)(1 * NSEC_PER_SEC)), dispatch_get_main_queue()) { () -> Void in
    
        self.imageView.sd_setImageWithURL(url, completed: { (image, error, _, _) -> Void in
        
            self.indicatorView.stopAnimating()
            
            if error != nil {
            
                print("下载大图片失败")
                
                return
            }
            
            self.layoutImageView(image)

        })
*/
    
    ///清除cell的子控件的相关属性 避免cell复用带来影响
    private func clearCellAttributes() {
    
        //transform恢复
        imageView.transform = CGAffineTransformIdentity
        
        //scrollView恢复
        scrollView.contentInset = UIEdgeInsetsZero
        scrollView.contentOffset = CGPointZero
        scrollView.contentSize = CGSizeZero
    }
    
    
    private func layoutImageView(image: UIImage) {
    
        let newSize = image.displaySize()
        
//        print("newSize\(newSize)")
        
        if newSize.height < UIScreen.height {
            
            let offsetY = (UIScreen.height-newSize.height) * 0.5
            
            //不能通过设置frame 否则缩小完毕后，会停在开始的(x, y)点那里
//            imageView.frame = CGRect(x: offsetX, y: offsetY, width: newSize.width, height: newSize.height)
            imageView.frame = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
            //通过设置contentInset ———— 结束滚动后 内容与scrollView的间距
            scrollView.contentInset = UIEdgeInsetsMake(offsetY, 0, offsetY, 0);
            
        }else {
            
            imageView.frame = CGRect(origin: CGPointZero, size: newSize)
            
            scrollView.contentSize = newSize
        }

        //重新布局  为什么没有效果？？？
//        layoutIfNeeded()
    }
    
    
//    override func layoutSubviews() {
//        
//        super.layoutSubviews()
//        
//        print("layoutSubviews:\(self.imageView.frame)")   //为什么frame是对的，最后显示出来的却与frame对不上，需要滚动后才能正确显示？？？
//    }
    
//    ///等比缩放图片
//    private func displaySize(image: UIImage) -> CGSize {
//        
//        let newWidth = UIScreen.width
//        
//        let oldWidth = image.size.width
//        let oldHeight = image.size.height
//        
//        let newHeight = oldHeight / oldWidth * newWidth
//    
//        return CGSize(width: newWidth, height: newHeight)
//    }
    

    //MARK: - 构造方法
    override init(frame: CGRect) {
        
        super.init(frame: frame)
        
        prepareUI()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    
    //MARK: - 准备UI
    private func prepareUI() {
    
        //添加子控件
        contentView.addSubview(scrollView)
        scrollView.addSubview(imageView)
        contentView.addSubview(indicatorView)
        
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        
        /*  cell中imageView的frame正确有效，而显示的frame却不正常，滚动后时正常时不正常的根源在于 这里通过frame来确定控件的位置和大小，却又把translatesAutoresizingMaskIntoConstraints属性关闭。不要忘了，关闭translatesAutoresizingMaskIntoConstraints表示使用autoLayout，而autolayout下，frame是无效的。 —————— 需要仔细阅读translatesAutoresizingMaskIntoConstraints官文说明，重新复习autoResizing与autolayout的区别？？？ */
//        imageView.translatesAutoresizingMaskIntoConstraints = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false

        //添加约束
        //scrollView
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[sv]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["sv": scrollView]))
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[sv]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["sv": scrollView]))
        
        
        //indicatorView
        contentView.addConstraint(NSLayoutConstraint(item: indicatorView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 0))
        contentView.addConstraint(NSLayoutConstraint(item: indicatorView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0))
        
        
        //设置scrollView的缩放系数
        scrollView.maximumZoomScale = 2.0
        scrollView.minimumZoomScale = 0.5
        
        scrollView.delegate = self
    }
    
    
    
    //MARK: - 懒加载
    ///scrollView
    private lazy var scrollView: UIScrollView = UIScrollView()
    
    ///imageView
    lazy var imageView: UIImageView = ZDImageView()
    
    ///指示器 indicatorView
    private lazy var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
}



extension ZDPhotoBrowserCell: UIScrollViewDelegate {

    ///指定哪个view需要缩放
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        
        return imageView
    }
    
    ///将要开始缩放
    func scrollViewWillBeginZooming(scrollView: UIScrollView, withView view: UIView?) {
        
//        print("scrollViewWillBeginZooming->frame:\(imageView.frame)")
//        print("scrollViewWillBeginZooming->bounds:\(imageView.bounds)")
    }

    ///已经缩放  会调用多次
    func scrollViewDidZoom(scrollView: UIScrollView) {
        
        /*  注意该方法内部打印发现  缩放改变的是frame 而不是bounds ———— bounds没有改变  */
//        print("缩放时->frame:\(imageView.frame)")
//        print("缩放时->bounds:\(imageView.bounds)")
        
        //打印transform发现 虽然设置了最小倍数为0.5  但是缩放到0.5后仍然会继续缩放，倍数会小于0.5，这直接导致结束缩放时，imageView会先跑到左上角(恢复到0.5)然后才执行我们的居中动画。———— 这里通过自定义imageView，覆盖系统的transform属性来设置其缩放系数不能小于0.5
        print("缩放时->transform:\(imageView.transform)")
        
        //在缩放时修改控制器背景view的透明度———— 如果修改控制器的view的话，imageView也会跟着变透明
        delegate?.viewForTransparent().alpha = imageView.transform.a < 1.0 ? imageView.transform.a : 1.0
    }
    
    ///结束缩放
    func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) {
        
        print("缩放完->frame:\(imageView.frame)")
//        print("缩放完->bounds:\(imageView.bounds)")
        
        //结束缩放后 居中显示  ————  不能使用bounds计算
        var offsetX = (UIScreen.width - imageView.frame.width) * 0.5
        var offsetY = (UIScreen.height - imageView.frame.height) * 0.5
        
        //图片放大后，offsetX或者offsetY可能小于0，如果直接设置contentInset，那么图片就没法滚动，应该将offsetX 和 offsetY都置为0(表示内容最终与scrollView的间距为0) 这样图片就能滚动了
        if offsetX < 0 {
        
            offsetX = 0
        }
        
        if offsetY < 0 {
        
            offsetY = 0
        }
        
//        UIView.animateWithDuration(0.25) { () -> Void in
//            
//            scrollView.contentInset = UIEdgeInsetsMake(offsetY, offsetX, offsetY, offsetX)
//        }
        
        //当缩小到一定大小时 退出图片浏览器 ———— 先缩放到缩略的位置 再关闭控制器
        if imageView.transform.a < 0.7 {
            
            //直接调用代理的dismiss方法发现imageView会先跑到左上角 再慢慢关闭
            //            delegate?.scaleDismiss()
            
            //获取缩略图
            let thumbImageView = model!.imageView!
            //坐标系转换
            let rect = thumbImageView.superview!.convertRect(thumbImageView.frame, toCoordinateSpace: self)
            
            UIView.animateWithDuration(0.25, animations: { () -> Void in
                
                //缩放到缩略的位置
                self.imageView.frame = CGRect(x: 0, y: 0, width: rect.width, height: rect.height)
        
                //设置contentInset将图片顶到指定位置
                scrollView.contentInset = UIEdgeInsetsMake(rect.origin.y, rect.origin.x, 0, 0)
                
                //设置contentOffset 解决缩放到最后 x方向 或 y方向有偏移问题
                scrollView.contentOffset = CGPoint(x: -rect.origin.x, y: -rect.origin.y)
                
                }, completion: { (_) -> Void in
                    
                    //缩放完成关闭控制器
                    self.delegate?.scaleDismiss()
            })
        }
        else {
        
            UIView.animateWithDuration(0.25) { () -> Void in
                
                scrollView.contentInset = UIEdgeInsetsMake(offsetY, offsetX, offsetY, offsetX)
            }
        }
    }
}

